package io.xiaojl.xj2ee.common.kit.security.web;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**  
 * <p>Title: JSEncryptWithRSA</p>  
 *
 * <p>Description: 配合前端JSEncrypt.js进行RSA加密数据，进行对应的解密</p>  
 * 使用方法：
 * 	1、前端：
 * 	<script src="bin/jsencrypt.min.js"></script>
 *	<script type="text/javascript">
 *	    var encrypt = new JSEncrypt();
 *	    encrypt.setPublicKey('java生成的公钥');
 *	    var encrypted = encrypt.encrypt('加密的字符串');
 *	</script>
 *	
 *	 2、后端：
 *	 JSEncryptWithRSA.decryptRSA(encrypted);
 *	 
 * @author jilong.xiao  
 * @date 2018年6月8日  
 */
public class JSEncryptWithRSA {
	private static final Logger log = LoggerFactory.getLogger(JSEncryptWithRSA.class);
	/** 生成密钥的因子 */
	private static final String KEY_SALT = "xiaojl";
	/** 公钥，用于加密 */
	public static String PUB_KEY ;
	/** 公私密钥对 */
	private static KeyPair KEY_PAIR;
	
	static{
		try {
			KEY_PAIR = initKey();// 公私密钥对 
			RSAPublicKey key = (RSAPublicKey)KEY_PAIR.getPublic();
			PUB_KEY = Base64.encodeBase64String(key.getEncoded());
			log.info("RSA加密算法 - 取得公钥：",PUB_KEY);
			
		} catch (Exception e) {
			log.error("RSA加密算法 - [初始化公私密钥]出现异常：",e);
			throw new RuntimeException(e);
		}
	}
	private static KeyPair initKey(){
		try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            SecureRandom random = new SecureRandom();
            random.setSeed(Base64.decodeBase64(KEY_SALT));// 初始化随机产生器 
            
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            generator.initialize(1024, random);
            return generator.generateKeyPair();
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
	
	/**
	 * <p>Title: decryptBase64</p>  
	 * <p>Description: 解密</p>  
	 * @param content
	 * @return
	 */
    public static String decryptRSA(String content) {
		try {
			log.debug("解密前content：",content);
			byte[] bs = Base64.decodeBase64(content);
			String text = new String(decrypt(bs));
			log.debug("解密后content：",text);
			
	        return text;
		} catch (Exception e) {
			log.error("RSA加密算法 - [解密]出现异常：",e);
			throw new RuntimeException(e);
		}
    }
	
	/**
	 * <p>Title: decrypt</p>  
	 * <p>Description: 解密[私钥]</p>  
	 * @param bytes
	 * @return
	 */
	private static byte[] decrypt(byte[] bytes) {
    	log.debug("解密的byte数据长度：",bytes.length);
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
            RSAPrivateKey pbk = (RSAPrivateKey)KEY_PAIR.getPrivate();
            cipher.init(Cipher.DECRYPT_MODE, pbk);
            byte[] plainText = cipher.doFinal(bytes);
            return plainText;
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
	
}
